import UIKit
import AVFoundation

class CameraOptions {
    var imageWidth: CGFloat = 0
    var imageHeight: CGFloat = 0
    var navTitle: String = ""
    var title: String = ""
    var subtitle: String = ""
    var doneButton: String = ""
    var cancelButton: String = ""
}

class CameraPicture: Codable {
    
    var image: String
    
    init(image: String) {
        self.image = image
    }
}

@objc(DHDCamera) class DHDCamera : CDVPlugin {

    var options: CameraOptions!
    var cameraController: CameraController!
    
    var pluginResult: CDVPluginResult?
    var command: CDVInvokedUrlCommand?
    var picCallbackId: String?
    
    override func pluginInitialize() {
        NotificationCenter.default.addObserver(self, selector: #selector(receiveNotification(notification:)), name: NSNotification.Name(rawValue: "CDVViewDidLayoutSubviewsNotification"), object: nil);
    }
    
    @objc func receiveNotification(notification: Notification) {
        if notification.name.rawValue == "CDVViewDidLayoutSubviewsNotification" {
        }
    }
    
    // @objc(getPicture:) public func getPicture(_ command: CDVInvokedUrlCommand) {
    //     picCallbackId = command.callbackId
    // }
    
    @objc(startCamera:) public func startCamera(_ command: CDVInvokedUrlCommand) {
        
        self.command = command        
        setupOptions(command: command)
        self.commandDelegate.run {
            
            DispatchQueue.main.async {
                self.cameraController = CameraController()
                self.cameraController.modalPresentationStyle = .overCurrentContext
                self.cameraController.cameraCompeletCompletion = { (cImage) -> Void in
                    let base64 = self.convertImageToBase64(image: cImage)
//                    self.pluginResult = CDVPluginResult(status: CDVCommandStatus_OK, messageAs: base64)
                    // self.commandDelegate!.send(self.pluginResult, callbackId: self.picCallbackId)
                    self.fireEvent(event: "picture", image: base64)
                }
                self.cameraController.options = self.options
                self.viewController.present(self.cameraController, animated: true, completion: nil)
            }
        }
    }
    
    @objc(stopCamera:) public func stopCamera(_ command: CDVInvokedUrlCommand) {
        
        self.cameraController.closeCamera()
        self.cameraController = nil

        self.picCallbackId = nil
        self.pluginResult = CDVPluginResult(status: CDVCommandStatus_OK)
        self.commandDelegate!.send(self.pluginResult, callbackId: self.command?.callbackId)
    }
    
    @objc(setTitle:) public func setTitle(_ command: CDVInvokedUrlCommand) {
        self.pluginResult = CDVPluginResult(status: CDVCommandStatus_OK)
        
        let navTitle = command.argument(at: 0, withDefault: "") as! String
        let title = command.argument(at: 1, withDefault: "") as! String
        let subtitle = command.argument(at: 2, withDefault: "") as! String
        
        self.cameraController.updateLabel(navTitle: navTitle, title: title, subTitle: subtitle)
        self.commandDelegate!.send(self.pluginResult, callbackId: self.command?.callbackId)
    }
    
    func setupOptions(command: CDVInvokedUrlCommand) {
        options = CameraOptions()
        options.imageWidth = command.argument(at: 0, withDefault: 0) as! CGFloat
        options.imageHeight = command.argument(at: 1, withDefault: 0) as! CGFloat
        options.navTitle = command.argument(at: 2, withDefault: "") as! String
        options.title = command.argument(at: 3, withDefault: "") as! String
        options.subtitle = command.argument(at: 4, withDefault: "") as! String
        options.doneButton = command.argument(at: 5, withDefault: "Done") as! String
        options.cancelButton = command.argument(at: 6, withDefault: "Cancel") as! String
    }
    
    func fireEvent(event: String, image: String) {
        let encoder = JSONEncoder()
        let picture = CameraPicture(image: image)
        let data = try! encoder.encode(picture)
        let jsonData = String(data: data, encoding: .utf8)!
        self.commandDelegate!.evalJs("cordova.plugins.dhdcamera.fireEvent('\(event)', \(jsonData))")
    }

}

extension DHDCamera {
    
    func convertImageToBase64(image: UIImage) -> String {
        let imageData = UIImagePNGRepresentation(image)!
        return imageData.base64EncodedString(options: Data.Base64EncodingOptions.lineLength64Characters)
    }
}
